

local Mino = class("Mino")


function Mino:ctor(sprId)
    self.super:ctor()
    self.sprId = sprId
    self.width = 0
    self.height = 0
    self.pos={x=0,y=0}
    self.shape = 0
    self.shapes = {}
    self.wallkickGap = 0 --检测左右是否碰撞到
    self.isFell = false --是否开始下落
    self.sprs = {}
end

function Mino:onStart()

end

function Mino:move(x, y)
    self.pos.x = x
    self.pos.y = y
    --g.log:info("222222", self.height, self.width)
    local shape = self:GetShape(self.shape)
    for y=1,self.height do
        for x=1,self.width do
            if shape~=nil and shape[y][x]>0 then
                local posX=x + self.pos.x
                local posY=y + self.pos.y
                --g.log:info("_______pos:", posX, posY)
                local bounds = self.sprs[y][x]:bounds()
                bounds:move2(posX, posY)
                self.sprs[y][x]:invalidate(true)
            end
        end
    end
end

function Mino:isCollision(grid, shape, pos)
    local sh = self:GetShape(shape)
    for y = 1, self.height do
        for x = 1, self.width do
            if sh ~= nil and sh[y][x]>0 then
                local posX = x + pos.x
                local posY = y + pos.y
                if posX <= 0 or posX > grid.width then
                    return true
                elseif posY > grid.height then
                    return true
                elseif not (grid.grid[posY][posX] == g.service.const.EMPTY_CELL_SPR) then
                    return true
                end
            end
        end
    end
end

--取形状
function Mino:GetShape(shape)
    if shape > 0 then
        return self.shapes[shape]
    end
    return nil
end


function Mino:draw(cx,cy)
    local shape = self:GetShape(self.shape)
    for y=1,self.height do
        for x=1,self.width do
            if shape~=nil and shape[y][x]>0 then
                local posX=cx+x-1 + self.pos.x
                local posY=cy+y-1 + self.pos.y
                if not self.sprs[y] then
                    self.sprs[y] = {}
                end
                self.sprs[y][x] = g.service.ui:createSprite(posX,posY)
            end
        end
    end
end


function Mino:GoDown(grid)
    local p={x=self.pos.x,y=self.pos.y}
    p.y=p.y+1
    if not self:isCollision(grid, self.shape, p) then
        self.pos = p
    else
        self.isFell=true
    end
    self:move(p.x, p.y)
end

function Mino:GoLeft(grid)
    local p={x=self.pos.x,y=self.pos.y}
    p.x=p.x-1
    if not self:isCollision(grid,self.shape,p) then
        self.pos=p
    end
end

function Mino:GoRight(grid)
    local p={x=self.pos.x,y=self.pos.y}
    p.x=p.x+1
    if not self:isCollision(grid, self.shape, p) then
        self.pos=p
    end
end

function Mino:doWallkick(grid, shape)
    if shape==2 or shape==4 then return end
    for gap=1, self.wallkickGap do
        -- try right
        local pRight = {x=self.pos.x+gap,y=self.pos.y}
        if not self:isCollision(grid, shape, pRight) then
            self.pos = pRight
            self.shape = shape
            return
        end

        -- try left
        local pLeft = {x=self.pos.x-gap, y=self.pos.y}
        if not self:isCollision(grid, shape, pLeft) then
            self.pos = pLeft
            self.shape = shape
            return
        end
    end
end

function Mino:DoRotation(clockwise, grid)
    local shape = self.shape
    if clockwise then
        shape = shape+1
    else
        shape = shape-1
    end
    if shape>4 then
        shape = 1
    elseif shape<1 then
        shape = 4
    end
    if not self:isCollision(grid, shape, self.pos) then
        self.shape = shape
    else
        self:doWallkick(grid, shape)
    end
end

function Mino:CopyToGrid(grid)
    local sh = self:GetShape(self.shape)
    for y=1,self.height do
        for x=1,self.width do
            if sh~=nil and sh[y][x]>0 then
                local posX=x+self.pos.x
                local posY=y+self.pos.y
                grid.grid[posY][posX] = self.sprId
            end
        end
    end
end

function Mino:IsGameOver(grid)
    return self:isCollision(grid, self.shape, self.pos)
end

--[[
    type: Z, S, L, J, T, I, O,
--]]
function Mino:create(type, sprId)
    g.log:info("Mino:create(sprId, type)", sprId, type)
    self.sprId = sprId
    if type == "Z" then
        self.width=3
        self.height=3
        self.shape=1
        self.wallkickGap=1
        self.shapes[1]={
            {1,1,0},
            {0,1,1},
            {0,0,0}
        }
        self.shapes[2]={
            {0,0,1},
            {0,1,1},
            {0,1,0}
        }
        self.shapes[3]={
            {0,0,0},
            {1,1,0},
            {0,1,1}
        }
        self.shapes[4]={
            {0,1,0},
            {1,1,0},
            {1,0,0}
        }
    elseif type == "S" then
        self.width=3
        self.height=3
        self.shape=1
        self.wallkickGap=1
        self.shapes[1]={
            {0,1,1},
            {1,1,0},
            {0,0,0}
        }
        self.shapes[2]={
            {0,1,0},
            {0,1,1},
            {0,0,1}
        }
        self.shapes[3]={
            {0,0,0},
            {0,1,1},
            {1,1,0}
        }
        self.shapes[4]={
            {1,0,0},
            {1,1,0},
            {0,1,0}
        }
    elseif type == "L" then
        self.width=3
        self.height=3
        self.shape=1
        self.wallkickGap=1
        self.shapes[1]={
            {0,0,1},
            {1,1,1},
            {0,0,0}
        }
        self.shapes[2]={
            {0,1,0},
            {0,1,0},
            {0,1,1}
        }
        self.shapes[3]={
            {0,0,0},
            {1,1,1},
            {1,0,0}
        }
        self.shapes[4]={
            {1,1,0},
            {0,1,0},
            {0,1,0}
        }
    elseif type == "J" then
        self.width=3
        self.height=3
        self.shape=1
        self.wallkickGap=1
        self.shapes[1]={
            {1,0,0},
            {1,1,1},
            {0,0,0}
        }
        self.shapes[2]={
            {0,1,1},
            {0,1,0},
            {0,1,0}
        }
        self.shapes[3]={
            {0,0,0},
            {1,1,1},
            {0,0,1}
        }
        self.shapes[4]={
            {0,1,0},
            {0,1,0},
            {1,1,0}
        }
    elseif type == "T" then
        self.width=3
        self.height=3
        self.shape=1
        self.wallkickGap=1
        self.shapes[1]={
            {0,1,0},
            {1,1,1},
            {0,0,0}
        }
        self.shapes[2]={
            {0,1,0},
            {0,1,1},
            {0,1,0}
        }
        self.shapes[3]={
            {0,0,0},
            {1,1,1},
            {0,1,0}
        }
        self.shapes[4]={
            {0,1,0},
            {1,1,0},
            {0,1,0}
        }
    elseif type == "I" then
        self.width=4
        self.height=4
        self.shape=1
        self.wallkickGap=2
        self.shapes[1]={
            {0,0,0,0},
            {1,1,1,1},
            {0,0,0,0},
            {0,0,0,0}
        }
        self.shapes[2]={
            {0,0,1,0},
            {0,0,1,0},
            {0,0,1,0},
            {0,0,1,0}
        }
        self.shapes[3]={
            {0,0,0,0},
            {0,0,0,0},
            {1,1,1,1},
            {0,0,0,0}
        }
        self.shapes[4]={
            {0,1,0,0},
            {0,1,0,0},
            {0,1,0,0},
            {0,1,0,0}
        }
    elseif type == "0" then
        self.width = 4
        self.height = 3
        self.shape = 1
        self.wallkickGap = 0
        self.shapes[1]={
            {0,1,1,0},
            {0,1,1,0},
            {0,0,0,0}
        }
        self.shapes[2]={
            {0,1,1,0},
            {0,1,1,0},
            {0,0,0,0}
        }
        self.shapes[3]={
            {0,1,1,0},
            {0,1,1,0},
            {0,0,0,0}
        }
        self.shapes[4]={
            {0,1,1,0},
            {0,1,1,0},
            {0,0,0,0}
        }
    end
    self:draw(0,0)

    return self
end







return Mino